package es

import (
	"context"
	"fmt"
	"github.com/olivere/elastic/v7"
	"github.com/zeromicro/go-zero/core/logx"
	"gozero-demo/internal/repo/es/es_constants"
	"net/http"
	"sync"
)

var (
	esClient *elastic.Client
	esOnce   sync.Once
	esErr    error
)

// GetESClient 返回 Elasticsearch 客户端单例实例
func GetESClient(ctx context.Context, cfg ESConfig) (*elastic.Client, error) {
	esOnce.Do(func() {
		// 创建一个不使用代理的 HTTP 客户端
		httpClient := &http.Client{
			Transport: &http.Transport{
				Proxy: http.ProxyURL(nil), // 禁用代理
			},
		}
		esClient, esErr = elastic.NewClient(
			elastic.SetURL(cfg.Hosts...),
			elastic.SetBasicAuth(cfg.Username, cfg.Password),
			elastic.SetSniff(false),
			elastic.SetHealthcheck(false),
			elastic.SetHttpClient(httpClient), // 使用自定义的 HTTP 客户端
		)
		if esErr != nil {
			logx.Error(fmt.Sprintf("failed to connect to Elasticsearch: %+v", esErr))
		}
	})
	// 初始化索引和文档结构
	/*
		indexName := "es_system_log_data"
		indexStruct := `
			{
				"mappings": {
					"properties": {
						"menu_id": {"type": "long"},
						"url": {"type": "keyword"},
						"content": {"type": "keyword"},
						"user_id": {"type": "long"},
						"create_time": {"type": "date", "format": "yyyy-MM-dd HH:mm:ss"}
					}
				}
			}
			`
		if err := initIndex(ctx, esClient, indexName, indexStruct); err != nil {
			return nil, err
		}
	*/

	for indexName, indexStruct := range es_constants.ESIndexDataMap {
		if err := initIndex(ctx, esClient, indexName, indexStruct); err != nil {
			return nil, err
		}
	}
	return esClient, esErr
}

// initIndex 是一个辅助函数，用于初始化索引
func initIndex(ctx context.Context, es *elastic.Client, indexName, indexStruct string) error {
	// 检查索引是否存在
	exists, err := es.IndexExists(indexName).Do(ctx)
	if err != nil {
		logx.Errorf("Failed to check index %s existence: %v", indexName, err)
		return err
	}

	if !exists {
		// 创建索引
		createIndex, err := es.CreateIndex(indexName).BodyString(indexStruct).Do(ctx)
		if err != nil {
			logx.Errorf("Failed to create index %s: %v", indexName, err)
			return err
		}
		if !createIndex.Acknowledged {
			logx.Errorf("Index %s creation not acknowledged", indexName)
			return fmt.Errorf("index %s creation not acknowledged", indexName)
		}
		logx.Infof("Index %s created", indexName)
	} else {
		//logx.Infof("Index %s already exists", indexName)
	}

	return nil
}
